







#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cmath>

#define q_Bool int
#define q_True 1
#define q_False 0

#define PI (3.1415926536)

using namespace std;

#include "goal.h"

class MyComplex {
public:
	double x;
	double y;
	double radius;
	MyComplex(double xx, double yy): x(xx), y(yy) {
		radius = sqrt(xx * xx + yy * yy);
	};
	MyComplex(void): x(1), y(0), radius(1) { };
	void set(double rad, double angle) {
		radius = rad;
		x = rad * cos(angle);
		y = rad * sin(angle);
	};
	double len() {
		return radius;
	};
};

MyComplex operator - (const MyComplex& a, const MyComplex& b) {
	MyComplex temp(a.x - b.x, a.y - b.y);
	return temp;
}

ostream& operator << (ostream &out, const MyComplex &a) {
	out << "(" << a.x << " ; " << a.y << ")";
	return out;
}

class VarSet {
public:
	vector < double > vars;
	int size;
	VarSet(double range, int ss = 3): size(ss) {
		for (int i = 0; i < size; i++) {
			double temp = (rand() % 20000 - 10000) * range / 10000.0;
			vars.push_back(temp);
		}
	};
	void varie(double range) {
		for (int i = 0; i < size; i++) {
			double temp = (rand() % 20000 - 10000) * range / 10000.0;
			vars[i] += temp;
		}
	};
};

ostream& operator << (ostream& out, const VarSet& a) {
	out << "(" << a.size << ")[ " << a.vars[0];
	for (int i = 1; i < a.size; i++) out << " , " << a.vars[i];
	out << "]";
	return out;
}

q_Bool comp(MyComplex *a, MyComplex *b, MyComplex *c) {
	return ((*a - *c).len() < (*b - *c).len());
}

double res(const Goal < MyComplex > &goal) {
	return (goal.best_result - *goal.goal).len();
}

q_Bool srtcmp(const Goal < MyComplex > &a, const Goal < MyComplex > &b) {
	if (b.result(b) - a.result(a) > 0) return q_True;
	return q_False;
}

template < class T >
void GoalsOut(const int &l, const int &r, vector < Goal < T > > &arr) {
	cout << endl << "--->" << endl;
	for (int j = l; j <= r; j++) {
		cout << j << ") ";
		arr[j].out();
	}
	cout << endl;
	return;
}

void MySort(int l, int r, vector < Goal < MyComplex > > &arr,
vector < VarSet > &vs, q_Bool (*cmp)(const Goal < MyComplex >&, const Goal < MyComplex >&)) {
//	cout << "Sorting(" << l << " ; " << r << ")" << endl;
//	GoalsOut(l, r, arr);
	int i = l, j = r;
	Goal < MyComplex > m = arr[(i + j) / 2];
	while (i <= j) {
		while (cmp(arr[i], m)) i++;
		while (cmp(m, arr[j])) j--;
		if (i <= j) {
//			cout << "changing " << i << " <-> " << j << endl;
//			arr[i].out();
//			arr[j].out();
//			cout << "||" << endl;
			
			Goal < MyComplex > temp1 = arr[i];
			arr[i] = arr[j];
			arr[j] = temp1;
//			arr[i].out();
//			arr[j].out();
//			cout << endl;
			VarSet temp2 = vs[i];
			vs[i] = vs[j];
			vs[j] = temp2;
			i++; j--;
		}
	}
	if (l < j) MySort(l, j, arr, vs, cmp);
	if (i < r) MySort(i, r, arr, vs, cmp);
}
		
int n, iterations;

int main() {
	freopen("test.in", "r", stdin);
	freopen("test.out", "w", stdout);
	srand(time(NULL));
	
	double cx, cy;
	cin >> iterations >> n >> cx >> cy;
	MyComplex c(cx, cy);
	
	vector < VarSet > vset;

	vector < MyComplex > x;

	vector < Goal < MyComplex > > ways;
	
	for (int i = 0; i < n; i++) {
		MyComplex tempMC(1, 0);
		x.push_back(tempMC);
		VarSet temp(10, 2);
		cout << temp << endl;
		vset.push_back(temp);
		cout << vset[i] << endl;
		Goal < MyComplex > tempG(x[i], c, &comp, &res);
		ways.push_back(tempG);
		ways[i].out();
	}

	double vrange = 30;
	for (int it = 0; it < iterations; it++) {
//		cout << "iteration( " << it << " / " << iterations << ")" << endl;
		for (int j = 0; j  < n; j++) {
			(*ways[j].val).set(vset[j].vars[0], 2 * PI * vset[j].vars[1]);
			ways[j].check();
		}
//		GoalsOut(0, n - 1, ways);
		MySort(0, n - 1, ways, vset, *srtcmp);
		
		
//		cout << endl << "SOrted!!!!!" << endl;
		
//		GoalsOut(0, n - 1, ways);

		int presize = n / 4;
		for (int j = presize; j < n; j++) {
			vset[j] = vset[rand() % presize];
			vset[j].varie(vrange);
		}
		vrange = vrange * 7.0 / 8.0;

	}
	GoalsOut(0, n - 1, ways);
	return 0;
}
